/*
 * Copyright 2011 Drew Wilder-Goodwin
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include "resources.h"
#include "main_dialog.h"
#include "globals.h"
#include "sound_tab.h"
#include "input_tab.h"
#include "system_tab.h"
#include "cmdline.h"
#include "utility.h"
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <assert.h>
#include <stdio.h>

/*
 * Get the Tab Control display area
 */
RECT get_tabcontrol_displayarea()
{
    RECT tabDisplayArea;
    assert(g_htabctrl != NULL);
    GetClientRect(g_htabctrl, &tabDisplayArea);
    SendMessageW(g_htabctrl, TCM_ADJUSTRECT, (WPARAM) FALSE,
                 (LPARAM) & tabDisplayArea);
    MapWindowPoints(g_htabctrl, g_hmaindialog, (LPPOINT) & tabDisplayArea,
                    2);
    return tabDisplayArea;
}

VOID resize_main_dialog(HWND hDialog, LONG width, LONG height)
{
    RECT dlus;
    LONG helpLeft, exitLeft, nextLeft, saveLeft;
    LONG buttonTop, buttonWidth, buttonHeight;
    LONG tabHeight;
    HWND handle;

    /* Get dialog units */
    dlus.left = 0;
    dlus.right = DLG_UNIT_DEF_WIDTH;
    dlus.top = 0;
    dlus.bottom = DLG_UNIT_DEF_HEIGHT;
    MapDialogRect(hDialog, &dlus);

    /* Set dialog size */
    SetWindowPos(hDialog, NULL, 0, 0, width, height, 0);

    /* Calculate widths/heights */
    buttonWidth =
        (DLG_MAIN_BUTTON_WIDTH / DLG_UNIT_DEF_WIDTH) * dlus.right;
    buttonHeight = (BUTTON_DEF_HEIGHT * dlus.bottom) / DLG_UNIT_DEF_HEIGHT;
    tabHeight = (height - 3 * WND_DEF_SPACING - buttonHeight);
    buttonTop = tabHeight + 2 * WND_DEF_SPACING;

    /* Set tab */
    handle = GetDlgItem(hDialog, DLG_MAIN_TAB);
    SetWindowPos(handle, NULL, WND_DEF_SPACING, WND_DEF_SPACING,
                 width - (2 * WND_DEF_SPACING), tabHeight, 0);

    /* Set buttons */
    helpLeft = WND_DEF_SPACING;
    exitLeft = width - WND_DEF_SPACING - buttonWidth;
    saveLeft = exitLeft - WND_DEF_SPACING - buttonWidth;
    nextLeft = saveLeft - WND_DEF_SPACING - buttonWidth;
    handle = GetDlgItem(hDialog, DLG_MAIN_HELP_BUTTON);
    SetWindowPos(handle, NULL, helpLeft, buttonTop, buttonWidth,
                 buttonHeight, 0);
    handle = GetDlgItem(hDialog, DLG_MAIN_EXIT_BUTTON);
    SetWindowPos(handle, NULL, exitLeft, buttonTop, buttonWidth,
                 buttonHeight, 0);
    handle = GetDlgItem(hDialog, DLG_MAIN_SAVE_BUTTON);
    SetWindowPos(handle, NULL, saveLeft, buttonTop, buttonWidth,
                 buttonHeight, 0);
    handle = GetDlgItem(hDialog, DLG_MAIN_NEXT_BUTTON);
    SetWindowPos(handle, NULL, nextLeft, buttonTop, buttonWidth,
                 buttonHeight, 0);
}

VOID edit_out_file(WCHAR * infile, WCHAR * outfile)
{
    int dotPos;
    int firstSlashPos;
    int slashPos;
    int newStartPos;
    for (dotPos = 0; dotPos < 1024; dotPos++) {
        if (infile[dotPos] == '.')
            break;
    }

    for (firstSlashPos = dotPos; firstSlashPos > 0; firstSlashPos--) {
        if (infile[firstSlashPos] == '\\')
            break;
    }

    slashPos = firstSlashPos + 1;
    for (newStartPos = firstSlashPos + 1; newStartPos < dotPos;
         newStartPos++) {
        outfile[newStartPos - slashPos] = infile[newStartPos];
    }
    outfile[dotPos] = '\0';
}

/*Save All Button*/
BOOL create_save_window(HWND hwnd)
{

    OPENFILENAMEW savefile;
    WCHAR outfile[MAX_FILENAME];
    WCHAR mainfile[MAX_FILENAME];
    WCHAR filter[] = {'T','e','x','t',' ','f','i','l','e',' ','(','*','.','t','x','t',')','\0','*','.','t','x','t','\\','\0','X','M','L',' ','f','i','l','e',' ','(','*','.','x','m','l',')','\0','*','.','x','m','l','\\','\0','\0'};

    ZeroMemory(&savefile, sizeof(OPENFILENAMEW));
    ZeroMemory(&outfile, sizeof(WCHAR)*MAX_FILENAME);
    ZeroMemory(&mainfile, sizeof(WCHAR)*MAX_FILENAME);

    savefile.lStructSize = sizeof(OPENFILENAMEW);
    savefile.lpstrFile = outfile;
    savefile.hwndOwner = hwnd;
    savefile.hInstance = g_hinstance;
    savefile.nMaxFile = sizeof(WCHAR)*MAX_FILENAME;

    /*struct contains a member called nFilterIndex which is set to the
      appropriate file type according to the lpstrFilter parsed in the 
      following line.  1 is for a text file and 2 is for an xml file*/


    savefile.lpstrFilter = filter;
    /*savefile.lpstrInitialDir = NULL;
    savefile.lpstrFileTitle = NULL;*/


    savefile.Flags = OFN_HIDEREADONLY;

    if(GetSaveFileNameW(&savefile))
    {
       edit_out_file(outfile, mainfile);
       if(savefile.nFilterIndex == 1)
       {
          return OutputToFile(mainfile, PLAIN);
       }
       else if(savefile.nFilterIndex == 2)
       {
          return OutputToFile(mainfile, XML);
       }
       else {
          return FALSE;
       }
    }
    else
    {
       messageboxw_resource(hwnd, STRING_ERROR_SAVEFILE_CREATE, STRING_COMMON_ERROR,
            MB_OK | MB_ICONINFORMATION);
       return FALSE;
    }

}

INT_PTR CALLBACK main_dialog_proc(HWND hwnd, UINT message, WPARAM wParam,
                                  LPARAM lParam)
{
    UINT id;
    LPNMHDR notify;
    char cmd[256];
    switch (message) {
    case WM_NOTIFY:
        notify = (LPNMHDR) lParam;
        switch (notify->code) {
        case TCN_SELCHANGE:
            id = SendMessageW(g_htabctrl, TCM_GETCURSEL, 0, 0);
            if (id != -1) {
                tab_control_display(&g_tabcontrol, id);
            }
            break;
        }
        /* WINE_FIXME: DOES THIS REQUIRE A BREAK? OR MISSING ON PURPOSE? */
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case DLG_MAIN_EXIT_BUTTON:
            DestroyWindow(g_hwndmain);
            break;
        case DLG_MAIN_HELP_BUTTON:
            sprintf(cmd, "wine ~/wine-git/programs/hh/hh.exe.so ~/wine-git/programs/dxdiag/DXHELP.chm");
            system(cmd);
            break;
        case DLG_MAIN_NEXT_BUTTON:
            id = SendMessageW(g_htabctrl, TCM_GETCURSEL, 0, 0);
            if (id != -1) {
                if (id >= g_tabcontrol.tabCount - 1)
                    id = 0;
                else
                    id++;
                SendMessageW(g_htabctrl, TCM_SETCURSEL, id, 0);
                tab_control_display(&g_tabcontrol, id);
            }
            break;
        case DLG_MAIN_SAVE_BUTTON:
            create_save_window(hwnd);
            break;
        }
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

VOID set_default_window_size(HWND hwnd)
{
    RECT rcClient, rcWindow, rcDialog;
    POINT ptDiff;
    GetClientRect(hwnd, &rcClient);
    GetWindowRect(hwnd, &rcWindow);
    ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
    ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
    rcDialog.top = 0;
    rcDialog.left = 0;
    rcDialog.right = WND_WIDTH;
    rcDialog.bottom = WND_HEIGHT;
    MapDialogRect(g_hmaindialog, &rcDialog);
    SetWindowPos(hwnd, NULL, 0, 0, rcDialog.right + ptDiff.x,
                 rcDialog.bottom + ptDiff.y, SWP_NOMOVE);
}

VOID create_main_dialog(HWND hwnd)
{
    WCHAR *text;
    TCITEMW tie;
    INT length;
    static WCHAR formatW[] = { '%', 'l', 's', '%', 'd', '\0' };
    int i, tabIndex;

    /* Create main dialog */
    g_hmaindialog = CreateDialogW(g_hinstance, MAKEINTRESOURCEW(DLG_MAIN),
                                  hwnd, main_dialog_proc);
    if (g_hmaindialog == NULL) {
        messageboxw_resource(hwnd, STRING_ERROR_MAIN_DIALOG_CREATE,
                             STRING_COMMON_ERROR,
                             MB_OK | MB_ICONEXCLAMATION);
    }

    /* Buttons */
    set_control_text_resource(g_hmaindialog, STRING_DLG_MAIN_HELP, DLG_MAIN_HELP_BUTTON);
    set_control_text_resource(g_hmaindialog, STRING_DLG_MAIN_EXIT, DLG_MAIN_EXIT_BUTTON);
    set_control_text_resource(g_hmaindialog, STRING_DLG_MAIN_NEXT, DLG_MAIN_NEXT_BUTTON);
    set_control_text_resource(g_hmaindialog, STRING_DLG_MAIN_SAVE, DLG_MAIN_SAVE_BUTTON);

    /* Tabs */
    tie.mask = TCIF_TEXT;
    g_htabctrl = GetDlgItem(g_hmaindialog, DLG_MAIN_TAB);

    /* System tab */
    tabIndex = 0;
    insert_tab_resource(g_htabctrl, STRING_TAB_SYSTEM, &tie, tabIndex);

    /* DirectX Files tab */
    tabIndex++;
    insert_tab_resource(g_htabctrl, STRING_TAB_DIRECTX, &tie, tabIndex);

    /* Display tab (n instances) */
    length = LoadStringW(g_hinstance, STRING_TAB_DISPLAY, (WCHAR*)&text, 0);
    if (g_dxdiagcom_root.numDisplayDevices == 1) {
        tabIndex++;
        tie.pszText = text;
        SendMessageW(g_htabctrl, TCM_INSERTITEMW, tabIndex,
                     (LPARAM) & tie);
    } else if (g_dxdiagcom_root.numDisplayDevices > 1) {
        for (i = 0; i < g_dxdiagcom_root.numDisplayDevices; i++) {
            tabIndex++;
            {
                /* Allocate on the stack */
                WCHAR text2[length+(((i+1)/10)+1)+1];
                tie.pszText = text2;
                wsprintfW(text2, formatW, text, i + 1);
                SendMessageW(g_htabctrl, TCM_INSERTITEMW, tabIndex,
                             (LPARAM) & tie);
            }
        }
    }

    /* Sound tab (n instances) */
    LoadStringW(g_hinstance, STRING_TAB_SOUND, (WCHAR*)&text, 0);
    if (g_dxdiagcom_root.numSoundDevices == 1) {
        tabIndex++;
        tie.pszText = text;
        SendMessageW(g_htabctrl, TCM_INSERTITEMW, tabIndex,
                     (LPARAM) & tie);
    } else if (g_dxdiagcom_root.numSoundDevices > 1) {
        for (i = 0; i < g_dxdiagcom_root.numSoundDevices; i++) {
            tabIndex++;
            {
                /* Allocate on the stack */
                WCHAR text2[length+(((i+1)/10)+1)+1];
                tie.pszText = text2;
                wsprintfW(text2, formatW, text, i + 1);
                SendMessageW(g_htabctrl, TCM_INSERTITEMW, tabIndex,
                             (LPARAM) & tie);
            }
        }
    }

    /* Music tab */
    tabIndex++;
    insert_tab_resource(g_htabctrl, STRING_TAB_MUSIC, &tie, tabIndex);

    /* Input tab */
    tabIndex++;
    insert_tab_resource(g_htabctrl, STRING_TAB_INPUT, &tie, tabIndex);

    /* Network tab */
    tabIndex++;
    insert_tab_resource(g_htabctrl, STRING_TAB_NETWORK, &tie, tabIndex);

    /* More Help tab */
    tabIndex++;
    insert_tab_resource(g_htabctrl, STRING_TAB_HELP, &tie, tabIndex);
}
